<template>
  <div
    class="upload"
    v-loading="loading"
    element-loading-background="rgba(0, 0, 0, 0.5)"
    :style="style"
  >
    <div v-if="tempImg || img" class="upload-file">
      <div class="mask">
        <span class="del" @click.stop="del">
          <el-icon><el-icon-delete /></el-icon>
        </span>
      </div>
      <el-image
        v-if="fileIsImg"
        class="image"
        :src="tempImg || img"
        :preview-src-list="[img]"
        fit="cover"
        hide-on-click-modal
        preview-teleported
        :z-index="9999"
      />
      <a v-else :href="img" class="file" target="_blank">
        <el-icon><el-icon-document /></el-icon>
      </a>
    </div>
    <div v-else class="upload-uploader" @click="fileSelect && showfileSelect()">
      <el-upload
        ref="uploadRef"
        class="uploader"
        :disabled="fileSelect"
        :auto-upload="!cropper"
        :on-change="change"
        :accept="accept"
        :action="action"
        :show-file-list="false"
        :before-upload="before"
        :on-success="success"
        :on-error="error"
        :http-request="request"
      >
        <slot>
          <div class="file-empty">
            <el-icon><component :is="icon" /></el-icon>
            <h4 v-if="title">{{ title }}</h4>
          </div>
        </slot>
      </el-upload>
    </div>
    <el-dialog
      title="剪裁"
      v-model="cropperDialogVisible"
      :width="580"
      destroy-on-close
    >
      <Cropper
        :src="cropperImg"
        :compress="compress"
        :aspectRatio="aspectRatio"
        ref="cropperRef"
      />
      <template #footer>
        <el-button @click="cropperDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="cropperSave">确 定</el-button>
      </template>
    </el-dialog>
    <el-dialog
      title="打开"
      v-model="fileSelectDialogVisible"
      :width="880"
      destroy-on-close
    >
      <FileSelect @submit="fileSelectSubmit">
        <template #do>
          <el-button @click="fileSelectDialogVisible = false">取 消</el-button>
        </template>
      </FileSelect>
    </el-dialog>
    <span style="display: none !important">
      <el-input v-model="img" />
    </span>
  </div>
</template>

<script setup>
import { defineAsyncComponent } from "vue";
import useUpload from "./useUpload";
import config from "@/config/upload";

const Cropper = defineAsyncComponent(() => import("@/components/Cropper"));
const FileSelect = defineAsyncComponent(() =>
  import("@/components/FileSelect")
);

// eslint-disable-next-line
const emits = defineEmits(["update:modelValue"]);
// eslint-disable-next-line
const props = defineProps({
  aspectRatio: { type: Number, default: NaN },
  compress: { type: Number, default: 1 },
  height: { type: Number, default: 120 },
  width: { type: Number, default: 120 },
  maxSize: { type: Number, default: config.maxSize },
  modelValue: { type: String, default: "" },
  action: { type: String, default: "" },
  title: { type: String, default: "" },
  icon: { type: String, default: "el-icon-plus" },
  accept: { type: String, default: "image/gif, image/jpeg, image/png" },
  fileSelect: { type: Boolean, default: false },
  cropper: { type: Boolean, default: false },
  apiObj: { type: Object, default: () => {} },
  onSuccess: { type: Function, default: () => true },
});

const {
  cropperRef,
  uploadRef,
  loading,
  fileIsImg,
  cropperDialogVisible,
  fileSelectDialogVisible,
  img,
  tempImg,
  cropperImg,
  style,
  showfileSelect,
  fileSelectSubmit,
  cropperSave,
  change,
  before,
  success,
  error,
  del,
  request,
} = useUpload(props, handleEmits);

function handleEmits(val) {
  emits("update:modelValue", val);
}
</script>

<style>
.upload + .upload {
  margin-left: 10px;
}
</style>

<style scoped lang="scss">
.el-form-item.is-error .upload-uploader {
  border: 1px dashed #f56c6c;
}

.upload {
  @include wh(120px, 120px);
  display: inline-block;
  vertical-align: top;
  box-sizing: border-box;
  .upload-file {
    position: relative;
    @include wh(100%, 100%);
    &:hover {
      .mask {
        display: inline-block;
      }
    }
    .mask {
      display: none;
      position: absolute;
      top: 0px;
      right: 0px;
      line-height: 1;
      z-index: 1;
      span {
        display: inline-block;
        @include wh(25px, 25px);
        line-height: 23px;
        text-align: center;
        cursor: pointer;
        color: $color-text;
        i {
          font-size: $color-text;
        }
      }
      .del {
        background: #f56c6c;
      }
    }
    .image {
      @include wh(100%, 100%);
      img {
        vertical-align: bottom;
      }
    }
    .file {
      @include wh(100%, 100%);
      @include fl();
      flex-direction: column;
      justify-content: center;
      border: 1px solid #dcdfe6;
      i {
        @include sc(30px, #409eff);
      }
    }
  }
}
.upload-uploader {
  border: 1px dashed #d9d9d9;
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  &:hover {
    border: 1px dashed #409eff;
  }
  .uploader {
    @include wh(100%, 100%);
  }
  .file-empty {
    @include wh(100%, 100%);
    @include fl();
    line-height: 1;
    flex-direction: column;
    justify-content: center;
    i {
      @include sc(28px, #8c939d);
    }
    h4 {
      font-weight: normal;
      margin-top: 10px;
      @include sc($font-size-small, #8c939d);
    }
  }
}
.upload-uploader:deep(.el-upload) {
  @include wh(100%, 100%);
}
</style>
